package com.example.hdz.recordplaypcm;

import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author hdz
 */
public class MainActivity extends Activity implements View.OnClickListener{

    private static final String TAG = "MainActivity";
    public static String m_sSDPath = "";
    private PCMRecord mPcmRecord;
    private PCMPlay mPcmPlay;

    private EditText mEtRecordFileName;
    private EditText mEtPlayFileName;
    private Button mBtnStartRecord;
    private Button mBtnStartPlay;

    private Handler mHandler;
    private AudioManager mAudioMgr;
    private AudioManager.OnAudioFocusChangeListener mAudioFocusChange = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initWidget();

        //判断设备是否插入了SD卡，且应用程序具有读写SD卡的权限
        try {
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                m_sSDPath = Environment.getExternalStorageDirectory().getCanonicalPath();
            }
        } catch (Exception e) {
            e.printStackTrace();
            m_sSDPath = "";
        }

        initLogic();

        // 参考：https://www.imooc.com/article/27402
        mAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mAudioFocusChange = new AudioManager.OnAudioFocusChangeListener() {
            @Override
            public void onAudioFocusChange(int focusChange) {
                switch (focusChange){
                    case AudioManager.AUDIOFOCUS_GAIN:
                        //当其他应用申请焦点之后又释放焦点会触发此回调
                        //可重新播放音乐
                        //我要求完全获得焦点，其他人需要释放焦点。获得焦点之后的操作
                        Log.d(TAG, "AUDIOFOCUS_GAIN");
                        startPlay();
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS:
                        //长时间丢失焦点,当其他应用申请的焦点为AUDIOFOCUS_GAIN时，
                        //会触发此回调事件，例如播放QQ音乐，网易云音乐等
                        //通常需要暂停音乐播放，若没有暂停播放就会出现和其他音乐同时输出声音
                        Log.d(TAG, "AUDIOFOCUS_LOSS");
                        stopPlay();
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        //短暂性丢失焦点，当其他应用申请AUDIOFOCUS_GAIN_TRANSIENT或AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE时，
                        //会触发此回调事件，例如播放短视频，拨打电话等。
                        //通常需要暂停音乐播放
                        //你会短暂的失去音频焦点，你可以暂停音乐，但不要释放资源，因为你一会就可以夺回焦点并继续使用
                        Log.d(TAG, "AUDIOFOCUS_LOSS_TRANSIENT");
                        stopPlay();
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                        //短暂性丢失焦点并作降音处理
                        Log.d(TAG, "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
                        break;
                }
            }
        };
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    private boolean requestAudioFocus() {
        if (mAudioMgr == null) {
            mAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        }
        int ret1 = 0;
        int ret2 = 0;
        if (mAudioMgr != null) {
            Log.i(TAG, "Request audio focus");
            ret1 = mAudioMgr.requestAudioFocus(mAudioFocusChange, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
            ret2 = mAudioMgr.requestAudioFocus(mAudioFocusChange, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
            if (ret1==AudioManager.AUDIOFOCUS_REQUEST_GRANTED || ret2==AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                Log.d(TAG, "request audio focus success." + ret1 + " " + ret2);
                return true;
            }
        }
        Log.i(TAG, "request audio focus failed. " + ret1 + " " + ret2);
        return false;
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btnStartPlay:
                startPlay();
                break;
            case R.id.btnStartRecord:
                startRecord();
                break;
            case R.id.btnStopPlay:
                stopPlay();
                // 停止播放，释放音频焦点
                mAudioMgr.abandonAudioFocus(mAudioFocusChange);
                break;
            case R.id.btnStopRecord:
                stopRecord();
                break;
            default:
                break;
        }
    }

    @Override
    protected void onDestroy() {
        if (mPcmRecord != null) {
            mPcmRecord.stopRecord();
            mPcmRecord = null;
        }
        if (mPcmPlay != null) {
            mPcmPlay.clean();
            mPcmPlay = null;
        }

        //释放焦点，该方法可根据需要来决定是否调用
        //若焦点释放掉之后，将不会再自动获得
        mAudioMgr.abandonAudioFocus(mAudioFocusChange);

        super.onDestroy();
    }

    private void initWidget() {
        mBtnStartRecord = (Button) findViewById(R.id.btnStartRecord);
        mBtnStartRecord.setOnClickListener(this);

        Button btnStopRecord = (Button) findViewById(R.id.btnStopRecord);
        btnStopRecord.setOnClickListener(this);

        mBtnStartPlay = (Button) findViewById(R.id.btnStartPlay);
        mBtnStartPlay.setOnClickListener(this);

        Button btnStopPlay = (Button)findViewById(R.id.btnStopPlay);
        btnStopPlay.setOnClickListener(this);

        mEtRecordFileName = (EditText) findViewById(R.id.etRecordFileName);
        mEtRecordFileName.setText("test.pcm");

        mEtPlayFileName   = (EditText) findViewById(R.id.etPlayFileName);
        mEtPlayFileName.setText("test.pcm");
    }

    private void initLogic() {
        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                switch(msg.what) {
                    case PCMPlay.PLAY_STATE_COMPLETE:
                        mPcmPlay.stop();
                        mEtPlayFileName.setEnabled(true);
                        mBtnStartPlay.setEnabled(true);
                        // 播放结束，释放音频焦点
                        mAudioMgr.abandonAudioFocus(mAudioFocusChange);
                        break;
                    default:
                        break;
                }
            }
        };

        mPcmRecord = new PCMRecord();
        mPcmPlay   = new PCMPlay(mHandler);

        //设置录音参数
        PCMParam pcmParamIn = PCMParam.GetPCMParamByDecodeType(PCMParam.AUDIO_16K_PCM, true);
        mPcmRecord.setRecordParam(pcmParamIn);

        PCMParam pcmParamOut = PCMParam.GetPCMParamByDecodeType(PCMParam.AUDIO_16K_PCM, false);
        mPcmPlay.setPlayParam(pcmParamOut);

        //启动App就开始录音，但是不保存到文件，这样才能不会延迟录音
        mPcmRecord.record();

        mPcmPlay.initPlay();
    }

    /**
     * 开始保存录音文件
     **/
    private void startRecord() {
        if (m_sSDPath.equals("")) {
            return;
        }
        String fileName = mEtRecordFileName.getText().toString();
        if (fileName.equals("")) {
            return;
        }

        //如果文件存在就先删除
        String sPath = m_sSDPath + "/" + fileName;
        File file = new File(sPath);
        if (file.exists()) {
            file.delete();
        }

        //设置录音文件路径
        mPcmRecord.setPCMFilePath(sPath);

        //开始将录音数据保存到文件中
        mPcmRecord.setIsSaveFile(true);

        //禁止修改文件名
        mEtRecordFileName.setEnabled(false);

        //禁止重新开始保存录音
        mBtnStartRecord.setEnabled(false);
    }

    /**
    *  停止保存录音文件
    **/
    private void stopRecord() {
        mPcmRecord.setIsSaveFile(false);
        mEtRecordFileName.setEnabled(true);
        mBtnStartRecord.setEnabled(true);
    }

    private void startPlay() {
        if (m_sSDPath.equals("")) {
            return;
        }
        String fileName = mEtPlayFileName.getText().toString();
        if (fileName.equals("")) {
            return;
        }

        String sPath = m_sSDPath + "/" + fileName;
        mPcmPlay.setPCMFilePath(sPath);

        // 开始播放，请求音频焦点
        requestAudioFocus();

        mEtPlayFileName.setEnabled(false);
        mBtnStartPlay.setEnabled(false);
        mPcmPlay.play();
    }

    private void stopPlay() {
        mPcmPlay.stop();
        mEtPlayFileName.setEnabled(true);
        mBtnStartPlay.setEnabled(true);
    }
}
